#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2022/3/24 19:51
# @Author  : Wang Yuhang
# @File    : get_bus_stop_line.py
# @Func    :

import requests
import pandas as pd
import json
import time
from bs4 import BeautifulSoup
from CoordinatesConverter import gcj02towgs84

# 设置value的显示长度为200，默认为50
pd.set_option('max_colwidth',200)
# 显示所有列，把行显示设置成最大
pd.set_option('display.max_columns', None)
# 显示所有行，把列显示设置成最大
pd.set_option('display.max_rows', None)


headers = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) ' \
          'Chrome/62.0.3202.94 Safari/537.36'
headers = {'User-Agent': headers}


def get_first_char(city_name):
    """
    确定城市所有公交名称首个字符的集合
    :param city_name: 城市拼音
    :return: 首字符列表
    """
    url = 'https://{}.8684.cn/list1'.format(city_name)
    data = requests.get(url, headers=headers)
    soup = BeautifulSoup(data.text, 'html.parser')
    initial = soup.find_all('div', {'class': 'tooltip-inner'})[3]
    initial = initial.find_all('a')
    return [i.get_text() for i in initial]


def get_line_name_by_first_char(city_name, first_char):
    """
    根据公交首字符，确定城市中以此首字符开头的所有公交线路名称
    :param city_name: 城市名称
    :param first_char: 首字符
    :return: 首字符对应的所有公交线路名称列表
    """
    url = 'https://{}.8684.cn/list{}'.format(city_name, first_char)
    data = requests.get(url, headers=headers)
    soup = BeautifulSoup(data.text, 'html.parser')
    busline = soup.find('div', {'class': 'list clearfix'})
    busline = busline.find_all('a')
    return [i.get_text() for i in busline]


def get_bus_info_from_amap(city_chinese_name, line_name):
    """
    爬取城市中某条公交线路的具体数据
    :param city_chinese_name: 城市的中文名
    :param line_name: 公交线路的名称
    :return: DataFrame，包含线路的ID、类型、名称、起始站点名称、起始运行时间，站台的ID、名称、经纬度、序号
    """
    url = 'https://restapi.amap.com/v3/bus/linename?s=rsv3&extensions=all&key={}' \
          '&output=json&city={}&offset=2&keywords={}&platform=JS'.format(key, city_chinese_name, line_name)
    r = requests.get(url).text
    rt = json.loads(r)

    try:
        if rt['buslines']:
            if len(rt['buslines']) == 0:                               # 没有公交线路数据
                print('INFO: no data in list..')
            else:
                du = []
                for cc in range(len(rt['buslines'])):                  # 遍历每一条公交线路数据
                    dl = []
                    line_id = rt['buslines'][cc]['id']                         # 线路ID
                    line_type = rt['buslines'][cc]['type']                     # 线路类型
                    line_name2 = rt['buslines'][cc]['name']                    # 线路名称
                    line_start_stop = rt['buslines'][cc]['start_stop']         # 起点站
                    line_end_stop = rt['buslines'][cc]['end_stop']             # 终点站
                    line_start_time = rt['buslines'][cc]['start_time']         # 开始时间
                    line_end_time = rt['buslines'][cc]['end_time']             # 结束时间

                    for st in rt['buslines'][cc]['busstops']:         # 遍历线路中的每一个站台
                        st_id = st['id']                                       # 站台的ID
                        st_name = st['name']                                   # 站台的名称
                        st_lon = st['location'].split(',')[0]                  # 站台的经纬度坐标
                        st_lat = st['location'].split(',')[1]                  # 站台的经纬度坐标
                        st_sequence = st['sequence']                           # 站台在线路中的序号
                        ds = [line_id, line_type, line_name2, line_start_stop, line_end_stop, line_start_time,
                              line_end_time, st_id, st_name, st_lon, st_lat, st_sequence]
                        dl.append(ds)
                    du += dl
                df = pd.DataFrame(du)
                return df
        else:
            pass
    except:
        print('ERROR: error..try it again..')
        time.sleep(2)
        get_bus_info_from_amap(city_chinese_name, line_name)


def get_city_all_bus_info():
    """
    获取城市所有公交线路的数据信息
    :return: DataFrame
    """
    first_chars = get_first_char(city_name)                                 # 获取城市内所有公交线路名称的首字符
    lines = []                                                              # 获取城市内所有公交线路名称
    for c in first_chars:
        char_map_lines = get_line_name_by_first_char(city_name, c)
        lines += char_map_lines
    # lines = ['1路', '10路', '2路']
    for i in range(0, len(lines)):                                          # 遍历每一条线路以获取详细信息
        print("数据获取：", str(i+1)+"/"+str(len(lines)))
        if i == 0:
            df = get_bus_info_from_amap(city_chinese_name, lines[i])
        else:
            df_tmp = get_bus_info_from_amap(city_chinese_name, lines[i])
            df = pd.concat([df, df_tmp], ignore_index=True)
    df.columns = ['line_id', 'line_type', 'line_name', 'line_start_stop', 'line_end_stop',
                  'line_start_time', 'line_end_time', 'st_id', 'st_name', 'st_lon', 'st_lat', 'st_sequence']
    df['lon'], df['lat'] = gcj02towgs84(df['st_lon'], df['st_lat'])
    df.drop(['st_lon', 'st_lat'], axis=1, inplace=True)

    df_subway = df[df['line_type'] == '地铁']
    df_bus = df[df['line_type'] != '地铁']
    df_subway.to_csv("./{}_subway.csv".format(city_name), index=False, encoding='utf-8-sig')        # 保存结果
    df_bus.to_csv("./{}_bus.csv".format(city_name), index=False, encoding='utf-8-sig')              # 保存结果


city_name = 'nanjing'
city_chinese_name = '南京'
key = '559bdffe35eec8c8f4dae959451d705c'
get_city_all_bus_info()


# data = pd.read_csv("nanjing_bus.csv", encoding='utf-8-sig')
# print(data['line_type'].value_counts())
#
# data2 = data[data['line_type'] == '地铁']
# print(data2['line_name'].value_counts())



